<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ElasticSearch 核心技术解析</title>
    <link href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
    <link href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            line-height: 1.6;
            color: #333;
            background-color: #f8fafc;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 0 20px;
        }
        .hero {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 80px 0;
            border-radius: 0 0 20px 20px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
        }
        .hero-title {
            font-size: 3rem;
            font-weight: 700;
            margin-bottom: 20px;
            text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        }
        .hero-subtitle {
            font-size: 1.5rem;
            opacity: 0.9;
            max-width: 800px;
            margin: 0 auto 30px;
        }
        .card {
            background: white;
            border-radius: 12px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            overflow: hidden;
        }
        .card:hover {
            transform: translateY(-5px);
            box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
        }
        .card-header {
            background: linear-gradient(90deg, #f3f4f6, #e5e7eb);
            padding: 15px 20px;
            border-bottom: 1px solid #e5e7eb;
            font-weight: 600;
            color: #4b5563;
        }
        .card-body {
            padding: 20px;
        }
        .code-block {
            background: #1e293b;
            color: #f8fafc;
            border-radius: 8px;
            padding: 15px;
            font-family: 'Courier New', Courier, monospace;
            overflow-x: auto;
        }
        .section-title {
            font-size: 2rem;
            font-weight: 600;
            margin: 40px 0 20px;
            color: #1e293b;
            position: relative;
            padding-left: 20px;
        }
        .section-title:before {
            content: "";
            position: absolute;
            left: 0;
            top: 8px;
            height: 24px;
            width: 6px;
            background: #6366f1;
            border-radius: 3px;
        }
        .subsection-title {
            font-size: 1.5rem;
            font-weight: 600;
            margin: 30px 0 15px;
            color: #334155;
        }
        .feature-icon {
            width: 40px;
            height: 40px;
            background: #6366f1;
            color: white;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-bottom: 15px;
        }
        .footer {
            background: #1e293b;
            color: white;
            padding: 30px 0;
            margin-top: 60px;
        }
        .footer a {
            color: #93c5fd;
            transition: color 0.2s;
        }
        .footer a:hover {
            color: #60a5fa;
            text-decoration: underline;
        }
        .highlight {
            background-color: #fef3c7;
            padding: 2px 4px;
            border-radius: 4px;
        }
        .image-container {
            background: #f3f4f6;
            padding: 15px;
            border-radius: 8px;
            margin: 20px 0;
            text-align: center;
        }
        .image-container img {
            max-width: 100%;
            height: auto;
            border-radius: 4px;
        }
        .image-caption {
            margin-top: 10px;
            font-size: 0.9rem;
            color: #64748b;
        }
    </style>
</head>
<body>
    <!-- Hero Section -->
    <section class="hero text-center">
        <div class="container">
            <h1 class="hero-title">ElasticSearch 核心技术解析</h1>
            <p class="hero-subtitle">深入探索分布式搜索引擎的核心原理、架构设计与最佳实践</p>
            <div class="flex justify-center space-x-4">
                <a href="#intro" class="px-6 py-3 bg-white text-indigo-600 rounded-full font-medium hover:bg-gray-100 transition">开始探索</a>
                <a href="#features" class="px-6 py-3 border border-white text-white rounded-full font-medium hover:bg-white hover:bg-opacity-10 transition">核心特性</a>
            </div>
        </div>
    </section>

    <!-- Main Content -->
    <div class="container py-12">
        <section id="intro">
            <h2 class="section-title">ElasticSearch 简介</h2>
            <div class="grid md:grid-cols-2 gap-8">
                <div class="card">
                    <div class="card-header">
                        <i class="fas fa-search mr-2"></i> ES 介绍
                    </div>
                    <div class="card-body">
                        <ul class="space-y-3">
                            <li class="flex items-start">
                                <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                                <span>基于Java语言和Lucene编写的分布式搜索引擎框架</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                                <span>提供统一的基于RESTful风格的WEB接口</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                                <span>支持多种编程语言的官方客户端API</span>
                            </li>
                            <li class="flex items-start">
                                <i class="fas fa-check text-green-500 mt-1 mr-2"></i>
                                <span>广泛应用于Github、Wikipedia等大型平台</span>
                            </li>
                        </ul>
                    </div>
                </div>
                <div class="card">
                    <div class="card-header">
                        <i class="fas fa-balance-scale mr-2"></i> ES vs Solr
                    </div>
                    <div class="card-body">
                        <div class="space-y-4">
                            <div>
                                <h4 class="font-medium text-gray-800">实时数据查询</h4>
                                <p class="text-gray-600">ES对实时数据查询效率基本不受影响，而Solr在数据变更时查询速度会下降</p>
                            </div>
                            <div>
                                <h4 class="font-medium text-gray-800">集群管理</h4>
                                <p class="text-gray-600">ES原生支持集群，Solr需要依赖Zookeeper</p>
                            </div>
                            <div>
                                <h4 class="font-medium text-gray-800">社区支持</h4>
                                <p class="text-gray-600">ES社区活跃度高，文档资料丰富</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <section id="inverted-index" class="mt-16">
            <h2 class="section-title">倒排索引原理</h2>
            <div class="card">
                <div class="card-header">
                    <i class="fas fa-sitemap mr-2"></i> 索引工作原理
                </div>
                <div class="card-body">
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h3 class="font-medium text-lg mb-3">正排索引</h3>
                            <p>以文档ID为关键字，记录文档中每个词的位置信息。查找时需要扫描每个文档中的词信息直到找出所有包含查询关键字的文档。</p>
                            <div class="image-container mt-4">
                                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1709523581394-6a0a3e6a-28b4-4735-b451-be16db76591d.png" alt="正排索引示意图">
                                <p class="image-caption">正排索引结构示意图</p>
                            </div>
                        </div>
                        <div>
                            <h3 class="font-medium text-lg mb-3">倒排索引</h3>
                            <p>以关键字为索引，记录出现这个词的所有文档ID及其位置。通过倒排索引可以快速定位包含特定词的文档。</p>
                            <div class="image-container mt-4">
                                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1709523581690-57d22c35-a1a3-46e7-88c0-99f98fb7aa32.png" alt="倒排索引示意图">
                                <p class="image-caption">倒排索引结构示意图</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="card mt-8">
                <div class="card-header">
                    <i class="fas fa-code-branch mr-2"></i> 倒排索引分词示例
                </div>
                <div class="card-body">
                    <div class="grid md:grid-cols-2 gap-8">
                        <div>
                            <h4 class="font-medium mb-3">原始文档</h4>
                            <div class="bg-gray-50 p-4 rounded-lg">
                                <p class="font-medium">文章1:</p>
                                <p>"老超在卡子门工作，我也是。"</p>
                                <p class="font-medium mt-3">文章2:</p>
                                <p>"小超在鼓楼工作。"</p>
                            </div>
                        </div>
                        <div>
                            <h4 class="font-medium mb-3">分词结果</h4>
                            <div class="bg-gray-50 p-4 rounded-lg">
                                <p class="font-medium">文章1分词:</p>
                                <p>老超 | 卡子门 | 工作 | 我 | 是</p>
                                <p class="font-medium mt-3">文章2分词:</p>
                                <p>小超 | 鼓楼 | 工作</p>
                            </div>
                        </div>
                    </div>
                    <div class="mt-6">
                        <h4 class="font-medium mb-3">倒排索引结果</h4>
                        <div class="code-block">
                            <pre>{
  "老超": { "文档": [1], "位置": [0], "频率": 1 },
  "小超": { "文档": [2], "位置": [0], "频率": 1 },
  "工作": { "文档": [1,2], "位置": [2,2], "频率": 2 },
  "卡子门": { "文档": [1], "位置": [1], "频率": 1 },
  "鼓楼": { "文档": [2], "位置": [1], "频率": 1 }
}</pre>
                        </div>
                    </div>
                </div>
            </div>
        </section>

        <section id="installation" class="mt-16">
            <h2 class="section-title">安装与配置</h2>
            <div class="card">
                <div class="card-header">
                    <i class="fas fa-download mr-2"></i> ES & Kibana 安装
                </div>
                <div class="card-body">
                    <h3 class="font-medium text-lg mb-3">系统配置</h3>
                    <p>调整最大进程数以满足ES需求：</p>
                    <div class="code-block mt-2">
                        <pre># vim /etc/sysctl.conf
vm.max_map_count=655360
# sysctl -p</pre>
                    </div>

                    <h3 class="font-medium text-lg mt-6 mb-3">Docker Compose 配置</h3>
                    <div class="code-block">
                        <pre>version: "3.1"
services:
  elasticsearch:
    image: daocloud.io/library/elasticsearch:6.5.4
    restart: always
    container_name: elasticsearch
    ports:
      - 9200:9200
  kibana:
    image: daocloud.io/library/kibana:6.5.4
    restart: always
    container_name: kibana
    ports:
      - 5601:5601
    environment:
      - elasticsearch_url=http://192.168.199.109:9200
    depends_on:
      - elasticsearch</pre>
                    </div>

                    <div class="grid md:grid-cols-2 gap-6 mt-6">
                        <div class="image-container">
                            <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1709523583873-9fb71845-b03e-47eb-9156-129502cb818c.png" alt="ES安装验证">
                            <p class="image-caption">ES安装验证</p>
                        </div>
                        <div class="image-container">
                            <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1709523584269-f80ff612-22a9-4907-b21f-fb0e5e35b9b7.png" alt="Kibana界面">
                            <p class="image-caption">Kibana界面</p>
                        </div>
                    </div>
                </div>
            </div>

            <div class="card mt-8">
                <div class="card-header">
                    <i class="fas fa-language mr-2"></i> 中文IK分词器安装
                </div>
                <div class="card-body">
                    <h3 class="font-medium text-lg mb-3">在线安装</h3>
                    <div class="code-block">
                        <pre>./bin/elasticsearch-plugin install \
https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.5.4/elasticsearch-analysis-ik-6.5.4.zip</pre>
                    </div>

                    <h3 class="font-medium text-lg mt-6 mb-3">离线安装</h3>
                    <div class="code-block">
                        <pre>./elasticsearch-plugin install file:./ik的文件路径</pre>
                    </div>

                    <h3 class="font-medium text-lg mt-6 mb-3">测试IK分词器</h3>
                    <div class="image-container">
                        <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1709523584940-d6aeed67-029e-4c08-a76c-143ecc24d1ee.png" alt="IK分词器测试">
                        <p class="image-caption">IK分词器测试</p>
                    </div>
                </div>
            </div>
        </section>

        <section id="basic-operations" class="mt-16">
            <h2 class="section-title">基本操作</h2>
            <div class="card">
                <div class="card-header">
                    <i class="fas fa-project-diagram mr-2"></i> ES 数据结构
                </div>
                <div class="card-body">
                    <div class="grid md:grid-cols-3 gap-6">
                        <div>
                            <h3 class="font-medium text-lg mb-3">索引(Index)</h3>
                            <p>类似关系型数据库中的数据库，是文档存储的逻辑空间。一个索引由一个或多个分片(Shard)组成。</p>
                            <div class="image-container mt-4">
                                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1709523585443-2053d56d-a7a1-4ed6-88f2-effc538ff02e.png" alt="索引结构">
                                <p class="image-caption">索引与分片</p>
                            </div>
                        </div>
                        <div>
                            <h3 class="font-medium text-lg mb-3">类型(Type)</h3>
                            <p>类似关系型数据库中的表，用于区分同一索引下不同的数据类型。ES 6.0后已不推荐使用多Type模式。</p>
                            <div class="image-container mt-4">
                                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1709523585788-8776f9c2-fd7d-4ca5-88f2-9d3d397f93ef.png" alt="类型结构">
                                <p class="image-caption">类型结构</p>
                            </div>
                        </div>
                        <div>
                            <h3 class="font-medium text-lg mb-3">文档(Document)</h3>
                            <p>类似关系型数据库中的行记录，是ES中存储的基本实体，以JSON格式存储。</p>
                            <div class="image-container mt-4">
                                <img src="https://cdn.nlark.com/yuque/0/2024/png/21449790/1709523586113-f1d5be06-3cb1-48dc-8b20-8e95a92f2e34.png" alt="文档结构">
                                <p class="image-caption">文档结构</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="card mt-8">
                <div class="card-header">
                    <i class="fas fa-terminal mr-2"></i> RESTful API 语法
                </div>
                <div class="card-body">
                    <div class="overflow-x-auto">
                        <table class="min-w-full divide-y divide-gray-200">
                            <thead class="bg-gray-50">
                                <tr>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">方法</th>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">URL</th>
                                    <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">描述</th>
                                </tr>
                            </thead>
                            <tbody class="bg-white divide-y divide-gray-200">
                                <tr>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">GET</td>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">/index</td>
                                    <td class="px-6 py-4 text-sm text-gray-500">查询索引信息</td>
                                </tr>
                                <tr>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">PUT</td>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">/index</td>
                                    <td class="px-6 py-4 text-sm text-gray-500">创建索引</td>
                                </tr>
                                <tr>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">DELETE</td>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">/index</td>
                                    <td class="px-6 py-4 text-sm text-gray-500">删除索引</td>
                                </tr>
                                <tr>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">POST</td>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">/index/type/_search</td>
                                    <td class="px-6 py-4 text-sm text-gray-500">查询文档</td>
                                </tr>
                                <tr>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">PUT</td>
                                    <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">/index/type/doc_id</td>
                                    <td class="px-6 py-4 text-sm text-gray-500">添加/修改文档</td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </section>

        <section id="java-client" class="mt-16">
            <h2 class="section-title">Java 客户端操作</h2>
            <div class="card">
                <div class="card-header">
                    <i class="fab fa-java mr-2"></i> Java 连接 ES
                </div>
                <div class="card-body">
                    <h3 class="font-medium text-lg mb-3">Maven 依赖</h3>
                    <div class="code-block">
                        <pre>&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.elasticsearch&lt;/groupId&gt;
        &lt;artifactId&gt;elasticsearch&lt;/artifactId&gt;
        &lt;version&gt;6.5.4&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.elasticsearch.client&lt;/groupId&gt;
        &lt;artifactId&gt;elasticsearch-rest-high-level-client&lt;/artifactId&gt;
        &lt;version&gt;6.5.4&lt;/version&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;</pre>
                    </div>

                    <h3 class="font-medium text-lg mt-6 mb-3">连接客户端</h3>
                    <div class="code-block">
                        <pre>public class ESClient {
    public static RestHighLevelClient getClient(){
        HttpHost httpHost = new HttpHost("192.168.199.109",9200);
        RestClientBuilder clientBuilder = RestClient.builder(httpHost);
        RestHighLevelClient client = new RestHighLevelClient(clientBuilder);
        return client;
    }
}</pre>
                    </div>
                </div>
            </div>

            <div class="card mt-8">
                <div class="card-header">
                    <i class="fas fa-database mr-2"></i> 索引操作
                </div>
                <div class="card-body">
                    <h3 class="font-medium text-lg mb-3">创建索引</h3>
                    <div class="code-block">
                        <pre>@Test
public void createIndex() throws IOException {
    // 1. 准备settings
    Settings.Builder settings = Settings.builder()
            .put("number_of_shards", 3)
            .put("number_of_replicas", 1);

    // 2. 准备mappings
    XContentBuilder mappings = JsonXContent.contentBuilder()
            .startObject()
                .startObject("properties")
                    .startObject("name").field("type","text").endObject()
                    .startObject("age").field("type","integer").endObject()
                    .startObject("birthday").field("type","date").field("format","yyyy-MM-dd").endObject()
                .endObject()
            .endObject();

    // 3. 封装Request
    CreateIndexRequest request = new CreateIndexRequest(index)
            .settings(settings)
            .mapping(type,mappings);

    // 4. 执行创建
    CreateIndexResponse resp = client.indices().create(request, RequestOptions.DEFAULT);
    System.out.println("resp:" + resp.toString());
}</pre>
                    </div>
                </div>
            </div>
        </section>

        <section id="queries" class="mt-16">
            <h2 class="section-title">查询操作</h2>
            <div class="grid md:grid-cols-2 gap-8">
                <div class="card">
                    <div class="card-header">
                        <i class="fas fa-filter mr-2"></i> Term & Terms 查询
                    </div>
                    <div class="card-body">
                        <h3 class="font-medium text-lg mb-3">Term 查询</h3>
                        <p>完全匹配，不会对关键字进行分词，直接去分词库中匹配内容。</p>
                        <div class="code-block mt-3">
                            <pre>POST /index/type/_search
{
  "query": {
    "term": {
      "field": {
        "value": "keyword"
      }
    }
  }
}</pre>
                        </div>

                        <h3 class="font-medium text-lg mt-6 mb-3">Terms 查询</h3>
                        <p>类似MySQL中的IN查询，匹配一个字段的多个值。</p>
                        <div class="code-block mt-3">
                            <pre>POST /index/type/_search
{
  "query": {
    "terms": {
      "field": ["value1", "value2"]
    }
  }
}</pre>
                        </div>
                    </div>
                </div>

                <div class="card">
                    <div class="card-header">
                        <i class="fas fa-search mr-2"></i> Match 查询
                    </div>
                    <div class="card-body">
                        <h3 class="font-medium text-lg mb-3">Match 查询</h3>
                        <p>智能匹配查询，会根据字段类型采用不同的查询方式。</p>
                        <div class="code-block mt-3">
                            <pre>POST /index/type/_search
{
  "query": {
    "match": {
      "field": "query text"
    }
  }
}</pre>
                        </div>

                        <h3 class="font-medium text-lg mt-6 mb-3">布尔 Match 查询</h3>
                        <p>使用AND或OR逻辑连接多个查询条件。</p>
                        <div class="code-block mt-3">
                            <pre>POST /index/type/_search
{
  "query": {
    "match": {
      "field": {
        "query": "text1 text2",
        "operator": "and"
      }
    }
  }
}</pre>
                        </div>
                    </div>
                </div>
            </div>

            <div class="card mt-8">
                <div class="card-header">
                    <i class="fas fa-chart-line mr-2"></i> 聚合查询
                </div>
                <div class="card-body">
                    <h3 class="font-medium text-lg mb-3">去重计数 (Cardinality)</h3>
                    <div class="code-block">
                        <pre>POST /index/type/_search
{
  "aggs": {
    "agg_name": {
      "cardinality": {
        "field": "field_name"
      }
    }
  }
}</pre>
                    </div>

                    <h3 class="font-medium text-lg mt-6 mb-3">范围统计 (Range)</h3>
                    <div class="code-block">
                        <pre>POST /index/type/_search
{
  "aggs": {
    "agg_name": {
      "range": {
        "field": "field_name",
        "ranges": [
          { "to": 50 },
          { "from": 50, "to": 100 },
          { "from": 100 }
        ]
      }
    }
  }
}</pre>
                    </div>
                </div>
            </div>
        </section>

        <section id="geo-search" class="mt-16">
            <h2 class="section-title">地理位置搜索</h2>
            <div class="card">
                <div class="card-header">
                    <i class="fas fa-map-marker-alt mr-2"></i> 地图经纬度搜索
                </div>
                <div class="card-body">
                    <h3 class="font-medium text-lg mb-3">创建地理位置索引</h3>
                    <div class="code-block">
                        <pre>PUT /map
{
  "mappings": {
    "map": {
      "properties": {
        "name": { "type": "text" },
        "location": { "type": "geo_point" }
      }
    }
  }
}</pre>
                    </div>

                    <h3 class="font-medium text-lg mt-6 mb-3">地理距离查询 (geo_distance)</h3>
                    <div class="code-block">
                        <pre>POST /map/map/_search
{
  "query": {
    "geo_distance": {
      "location": {
        "lon": 116.403981,
        "lat": 39.914492
      },
      "distance": "3km"
    }
  }
}</pre>
                    </div>

                    <h3 class="font-medium text-lg mt-6 mb-3">地理边界框查询 (geo_bounding_box)</h3>
                    <div class="code-block">
                        <pre>POST /map/map/_search
{
  "query": {
    "geo_bounding_box": {
      "location": {
        "top_left": { "lon": 116.32, "lat": 39.95 },
        "bottom_right": { "lon": 116.43, "lat": 39.90 }
      }
    }
  }
}</pre>
                    </div>
                </div>
            </div>
        </section>
    </div>

    <!-- Footer -->
    <footer class="footer">
        <div class="container text-center">
            <p>技术小馆</p>
            <p class="mt-2"><a href="http://www.yuque.com/jtostring">http://www.yuque.com/jtostring</a></p>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true
            }
        });
    </script>
</body>
</html>